package com.g.ocache.impl;

import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

import com.g.ocache.event.StoreEvent;
import com.g.ocache.event.StoreEventListener;
import com.g.ocache.event.StoreEventPublisher;



/**
 * 
 * @author Jingqi Xu
 */
public final class SyncStoreEventPublisher<K, V> implements StoreEventPublisher<K, V> {
	//
	private final AtomicBoolean started = new AtomicBoolean(false);
	private final CopyOnWriteArrayList<StoreEventListener<K, V>> listeners;
	
	/**
	 * 
	 */
	public SyncStoreEventPublisher() {
		this.listeners = new CopyOnWriteArrayList<StoreEventListener<K, V>>();
	}
	
	/**
	 * 
	 */
	public boolean isRunning() {
		return started.get();
	}
	
	public void start() {
		// Precondition checking
		if(!started.compareAndSet(false, true)) {
			throw new IllegalStateException("the publisher has already been started");
		}
		
		// NOP
	}
	
	public void stop() {
		// Precondition checking
		if(!started.compareAndSet(true, false)) {
			return;
		}
		
		// NOP
	}
	
	/**
	 * 
	 */
	public void publish(StoreEvent<K, V> event) {
		//
		if(listeners == null) {
			return;
		}
		
		//
		for(StoreEventListener<K, V> listener: listeners) {
			listener.onEvent(event);
		}
	}
	
	public final boolean addStoreEventListener(StoreEventListener<K, V> listener) {
		if(listener == null || listeners.contains(listener)) {
			return false;
		} else {
			return listeners.add(listener);
		}
	}
	
	public final boolean removeStoreEventListener(StoreEventListener<K, V> listener) {
		if(listener == null) {
			return false;
		} else {
			return listeners.remove(listener);
		}
	}
}
